home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / c / library / dos / multitsk / vid_scrn / vid_clok.c next >
Encoding:
C/C++ Source or Header  |  1987-11-22  |  21.2 KB  |  486 lines

  1. /*
  2.  
  3.   VID_CLOK.C  -  by Jerry Joplin [70441,2627] CIS
  4.                  This is a public domain demonstration of
  5.                  the vid_scrn library of fast video access
  6.                  functions.
  7.  
  8.                  The .EXE file can be run as a very well behaved
  9.                  window under MicroSoft Windows(tm) or QuarterDeck's
  10.                  DESQview(tm).  Set up a program information file
  11.                  for vid_clok.exe saying that the program does NOT
  12.                  directly modify the screen or any other memory.
  13.  
  14.                  The provided version of the .EXE file was created by
  15.                  using a variant of the C0.ASM file provided with
  16.                  TURBOC(tm) compiler version 1.0 in order to get the
  17.                  memory the program needed down to the bare bones
  18.                  minimum.  The .EXE file should run fine in window
  19.                  given 15k of memory.
  20.  
  21. */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include <dos.h>
  26. #include "vid_scrn.h"
  27.  
  28. #define normal  0x07                       /* Character attributes            */
  29. #define reverse 0x70
  30.  
  31. char hour;
  32. char min;                                  /* Global clock variables to hold  */
  33. char sec;                                  /* the current time                */
  34.  
  35. struct {
  36.    int value;
  37.    int ypos;
  38.    int xpos;
  39.    } clock_dig[] = {                       /* The digital clock will contain  */
  40.       10, 5, 3,                            /* four individual digits.  This   */
  41.       10, 5, 13,                           /* array holds structures of the   */
  42.       10, 5, 27,                           /* digit's value and position      */
  43.       10, 5, 37,
  44.       } ;
  45.  
  46.  
  47. /******************************************************************************/
  48.  
  49. main()
  50. {
  51.    int i;
  52.    register unsigned KeyStatus ;
  53.    register unsigned LastStatus = 0;
  54.  
  55.    vid_clearbox(0,0,24,79,normal);         /* Set up initial screen           */
  56.    vid_drawbox(0,0,19,48, normal, 1);      /* Draw box around digits          */
  57.    show_left_shift(1,normal);              /* Show initial shift status       */
  58.    show_right_shift(1,normal);
  59.    vid_putc(' ',7,24,reverse);             /* Make the 'colon' between hours  */
  60.    vid_putc(' ',13,24,reverse);            /* and minutes  and set the cursor */
  61.    vid_poscurs(13,24);                     /* below it.  Gives the colon a    */
  62.                                            /* blinking appearance in MS Windows*/
  63.  
  64.                                            /* Show instructions               */
  65.    vid_puts("Depress shift for seconds, or any other key to exit",21,0,normal);
  66.  
  67.    while (!kbhit()) {                      /* Main loop                       */
  68.  
  69.       getdostime(&hour,&min,&sec);         /* Get system time                 */
  70.       KeyStatus = keyflags() & 0x3;        /* and shift key status            */
  71.  
  72.       show_am_pm();                        /* Indicate the AM or PM setting   */
  73.  
  74.       if (KeyStatus) {                     /* If a shift key is down  then..  */
  75.  
  76.                                            /* Check to see if the status of   */
  77.                                            /* the right shift has changed     */
  78.          if ( (KeyStatus & 0x1) != (LastStatus & 0x1) ) {
  79.             if (KeyStatus & 0x1)
  80.                show_right_shift(2,reverse);/* Show indicator if its pressed   */
  81.  
  82.             else
  83.                show_right_shift(1,normal); /* else right shift isn't pressed  */
  84.             }
  85.  
  86.                                            /* Check to see if the status of   */
  87.                                            /* the left shift has changed      */
  88.          if ( (KeyStatus & 0x2) != (LastStatus & 0x2) ) {
  89.             if (KeyStatus & 0x2)
  90.                show_left_shift(2,reverse); /* Show indicator for left shift   */
  91.             else
  92.                 show_left_shift(1,normal);
  93.             }
  94.  
  95.  
  96.          show_seconds();                   /* Will always show seconds if     */
  97.                                            /* one of the shift keys is down   */
  98.          }
  99.  
  100.       else {                               /* If a shift key is not pressed   */
  101.  
  102.          if (LastStatus & 0x1) {           /* erase any shift key indicators  */
  103.             show_right_shift(1,normal);    /* if we haven't already done so   */
  104.             }
  105.          if (LastStatus & 0x2) {
  106.             show_left_shift(1,normal);
  107.             }
  108.          show_time();                      /* show the hours and minutes      */
  109.          }
  110.       LastStatus = KeyStatus;              /* Save this shift key status for  */
  111.                                            /* next check.                     */
  112.       }
  113.  
  114.    getkey();                               /* Get the keystroke that caused   */
  115.                                            /* kbhit to become positive        */
  116.  
  117.    vid_poscurs(0,0);                       /* Set the cursor position         */
  118.    practice_window();                      /* Show windowing technique        */
  119.    vid_clearbox(0,0,24,79,normal);         /* and clear the screen at exit    */
  120. }
  121.  
  122.  
  123. /******************************************************************************
  124. **
  125. **  Show the windowing potentials while giving a little plug for the author
  126. */
  127.  
  128.  
  129. practice_window()
  130. {
  131.    register unsigned i;
  132.    register char *buffptr;
  133.                                            /* Allocate space to hold the      */
  134.                                            /* contents of video memory about  */
  135.                                            /* to be covered up                */
  136. /******************************************************************************
  137. NOTE: commented out to avoid the call to malloc so we could use the bare bones
  138.       minimum startup code.  The savebuff is instead a static array.
  139.  
  140.    void *savebuff;
  141.    if ( (savebuff=malloc(2400)) == NULL)
  142.       return;
  143. *******************************************************************************/
  144.    static char savebuff[2400];
  145.  
  146.  
  147.    buffptr = savebuff;                     /* Prepare to save the contents    */
  148.    for (i = 0; i < 20; i++){               /* Save 20 rows                    */
  149.       vid_memread((void *)buffptr,i,0,60); /* of 60 chars and attributes      */
  150.       buffptr += 120;                      /* increment buffer pointer by     */
  151.                                            /* character count * 2             */
  152.       }
  153.  
  154.    vid_clearbox(0,0,19,59,normal);         /* Start window with clean slate   */
  155.    vid_setbox(0,213,205,184,179,190,205,212,179);/* set a box rendition set   */
  156.    vid_drawbox(0,0,19,59,reverse,0);       /* and draw the newly defined box  */
  157.  
  158.    vid_puts("            Closing Window, hit any key to exit           ",1,1,reverse);
  159.    vid_puts("This digitial clock was a demonstration of a library"      ,3,2,normal);
  160.    vid_puts("of fast video screen access routines that are well"        ,4,2,normal);
  161.    vid_puts("behaved  *just enough*  to run in concurrently"            ,5,2,normal);
  162.    vid_puts("executing windowed tasks under control programs such as"   ,6,2,normal);
  163.    vid_puts("MicroSoft Windows (a registered trademark of MicroSoft)"   ,7,2,normal);
  164.    vid_puts("and DESQview. (a registered trademark of Quarterdeck)"     ,8,2,normal);
  165.    vid_puts("Please send any comments, improvements, enhancements,"     ,11,2,normal);
  166.    vid_puts("or suggestions to:"                                        ,12,2,normal);
  167.    vid_puts("  Jerry Joplin     [70441,2627] CIS"                       ,14,2,normal);
  168.    vid_puts("  3535 Plainsman Lane #F88"                                ,15,2,normal);
  169.    vid_puts("  Bryan, TX  77802"                                        ,16,2,normal);
  170.  
  171.    while (!getkey());
  172.  
  173.    buffptr = savebuff;                     /* Prepare to restore the covered  */
  174.    for (i = 0; i < 20; i++){               /* contents of video memory        */
  175.       vid_memwrite((void *)buffptr,i,0,60);/* Restore the 20 rows of          */
  176.       buffptr += 120;                      /* 60 chars and attributes         */
  177.       }
  178.  
  179.    for (i=0 ; i < 0xffff; i++)             /* Briefly show the restore        */
  180.       ;
  181. }
  182.  
  183.  
  184.  
  185. /******************************************************************************
  186. **  Show an indication that the Right shift key has been pressed
  187. */
  188.  
  189. show_left_shift(boxset,attr)
  190. int boxset;
  191. int attr;
  192. {
  193.    vid_drawbox(1,3,3,14,normal,boxset);
  194.    vid_puts("Left Shift",2,4,attr);
  195. }
  196.  
  197.  
  198. /******************************************************************************
  199. **  Show an indication that the Right shift key has been pressed
  200. */
  201.  
  202. show_right_shift(boxset,attr)
  203. int boxset;
  204. int attr;
  205. {
  206.    vid_drawbox(1,29,3,41,normal,boxset);
  207.    vid_puts("Right Shift",2,30,attr);
  208. }
  209.  
  210.  
  211. /******************************************************************************
  212. **  Show the current time in 12 hour am/pm format
  213. */
  214.  
  215. show_time()
  216. {
  217.    if (hour == 0 ) {                       /* if hour is 0 then set it        */
  218.       hour = 12;                           /* to 12 a.m.                      */
  219.       }
  220.    else if (hour > 12) {                   /* when hour is greater than 12    */
  221.       hour -= 12;                          /* then substract 12               */
  222.       }
  223.  
  224.    /*                                                                         */
  225.    /* There are four available digits on the screen clock , so set the two    */
  226.    /* left digits to the hour and the two right digits to the minute.         */
  227.    /*                                                                         */
  228.  
  229.    clock_dig[1].value = hour % 10;         /* Split the hour into 2 digits    */
  230.    hour /= 10;
  231.    clock_dig[0].value = hour % 10;
  232.  
  233.    clock_dig[3].value = min % 10;          /* Split the minute into 2 digits  */
  234.    min /= 10;
  235.    clock_dig[2].value = min % 10;
  236.  
  237.    show_digits();                          /* and display the digits          */
  238. }
  239.  
  240.  
  241. /******************************************************************************
  242. **  Show the current minutes and seconds
  243. */
  244.  
  245. show_seconds()
  246. {
  247.    clock_dig[1].value = min % 10;          /* Split the minute into 2 digits  */
  248.    min /= 10;
  249.    clock_dig[0].value = min % 10;
  250.  
  251.    clock_dig[3].value = sec % 10;          /* Split the second into 2 digits  */
  252.    sec /= 10;
  253.    clock_dig[2].value = sec % 10;
  254.  
  255.    show_digits();                          /* and display the digits          */
  256. }
  257.  
  258.  
  259. /******************************************************************************
  260. **  Display the AM or PM indicator
  261. */
  262.  
  263. static int pm_save = 2;
  264. static int pm = 0;
  265.  
  266. show_am_pm()
  267. {
  268.  
  269.    if (hour > 11 )                         /* Establish AM or PM setting      */
  270.       pm = 1;
  271.    else
  272.       pm = 0;
  273.  
  274.    if (pm_save != pm) {                    /* Check to see if the current     */
  275.                                            /* displayed value should change   */
  276.       pm_save = pm;                        /* If so then save this new value  */
  277.       if (pm)                              /* and display a P.M.              */
  278.          vid_puts("P.M.",18,2,normal);     /*                                 */
  279.       else                                 /*                                 */
  280.          vid_puts("A.M.",18,2,normal);     /* or an AM depending on the hour  */
  281.       }
  282.  
  283.    /*                                                                         */
  284.    /* NOTE: pm_save is initially 2 so the first time through the AM/PM        */
  285.    /* indicator will be displayed since the pm flag can only be 0 or 1        */
  286.    /* and the comparison of the pm flag to pm_save is what deterimes if       */
  287.    /* it should be displayed or not.                                          */
  288.    /*                                                                         */
  289. }
  290.  
  291.  
  292.  
  293. /******************************************************************************
  294. **  Define the clocks digits
  295. */
  296.  
  297. struct digit_mask {          /* The clocks digits are composed of 7 lines     */
  298.    unsigned top  ;           /*                                               */
  299.    unsigned upl  ;           /*                top                            */
  300.    unsigned upr  ;           /*               ------                          */
  301.    unsigned mid  ;           /*              |      |                         */
  302.    unsigned lowl ;           /*        upl   |      |  upr                    */
  303.    unsigned lowr ;           /*              | mid  |                         */
  304.    unsigned bot  ;           /*               ------                          */
  305.    unsigned junk ;           /*              |      |                         */
  306.    }                         /*        lowl  |      |  lowr                   */
  307.                              /*              | bot  |                         */
  308.                              /*               ------                          */
  309.                              /*                                               */
  310.                              /* Define the individual digits in an array      */
  311.      digit[] = {             /*                                               */
  312.         { 1,1,1,0,1,1,1,0 }, /*  0  = top,upl,upr,    lowl,lowr,bot           */
  313.         { 0,0,1,0,0,1,0,0 }, /*  1  =         upr,         lowr               */
  314.         { 1,0,1,1,1,0,1,0 }, /*  2  = top,   ,upr,mid,lowl,     bot           */
  315.         { 1,0,1,1,0,1,1,0 }, /*  3  = top,    upr,mid,     lowr,bot           */
  316.         { 0,1,1,1,0,1,0,0 }, /*  4  =     upl,upr,mid,     lowr               */
  317.         { 1,1,0,1,0,1,1,0 }, /*  5  = top,upl,    mid,     lowr,bot           */
  318.         { 1,1,0,1,1,1,1,0 }, /*  6  = top,upl,    mid,lowl,lowr,bot           */
  319.         { 1,0,1,0,0,1,0,0 }, /*  7  = top,    upr,         lowr               */
  320.         { 1,1,1,1,1,1,1,0 }, /*  8  = top,upl,upr,mid,lowl,lowr,bot           */
  321.         { 1,1,1,1,0,1,0,0 }, /*  9  = top,upl,upr,mid,     lowr               */
  322.         { 0,0,0,0,0,0,0,0 }, /* 10  =                                         */
  323.         };                   /*NOTE: 10 is the special case of no lines       */
  324.  
  325. static int dsave[4][7] = {
  326.    { 0,0,0,0,0,0,0 },        /* Array of last status for the individual lines */
  327.    { 0,0,0,0,0,0,0 },        /* of the digits. It is undesirable to redisplay */
  328.    { 0,0,0,0,0,0,0 },        /* the same item under MS Windows on an 8088     */
  329.    { 0,0,0,0,0,0,0 },        /* or when several windows are active in DESQview*/
  330.    } ;
  331.  
  332. /******************************************************************************
  333. **  Display the clocks digits
  334. */
  335.  
  336. show_digits()
  337. {
  338.    register int i;
  339.    register int j;
  340.    int row,col,num;
  341.  
  342.    for ( i = 0; i < 4; i++) {              /* Display the four digits         */
  343.  
  344.       row = clock_dig[i].ypos;             /* Get this digits starting row    */
  345.       col = clock_dig[i].xpos;             /* column,                         */
  346.       j = clock_dig[i].value;              /* and current value               */
  347.  
  348.       if ( i == 0 && j == 0 )              /* If the left most digit is zero  */
  349.          j = 10;                           /* then set it to empty digit(10)  */
  350.  
  351.                                            /* Display the top line            */
  352.       if ( (num = digit[j].top) != dsave[i][0] ) { /* only if it has changed  */
  353.          dsave[i][0] = num;                        /* save the new value      */
  354.          horiz_bar(num, row,   col+1);
  355.          }
  356.                                            /* Display the upper left line     */
  357.       if ( (num = digit[j].upl) != dsave[i][1] ) { /* only if it has changed  */
  358.          dsave[i][1] = num;                        /* save the new value      */
  359.          vertl_bar(num, row+1, col);
  360.          }
  361.  
  362.                                            /* Display the upper right line    */
  363.       if ( (num = digit[j].upr) != dsave[i][2] ) { /* only if it has changed  */
  364.          dsave[i][2] = num;                        /* save the new value      */
  365.          vertl_bar(num, row+1, col+7);
  366.          }
  367.  
  368.                                            /* Display the middle line         */
  369.       if ( (num = digit[j].mid) != dsave[i][3] ) { /* only if it has changed  */
  370.          dsave[i][3] = num;                        /* save the new value      */
  371.          horiz_bar(num, row+6, col+1);
  372.          }
  373.  
  374.                                            /* Display the lower left line     */
  375.       if ( (num = digit[j].lowl) != dsave[i][4] ) {/* only if it has changed  */
  376.          dsave[i][4] = num;                        /* save the new value      */
  377.          vertl_bar(num,row+7, col);
  378.          }
  379.  
  380.                                            /* Display the lower right line    */
  381.       if ( (num = digit[j].lowr) != dsave[i][5] ) {/* only if it has changed  */
  382.          dsave[i][5] = num;                        /* save the new value      */
  383.          vertl_bar(num,row+7, col+7);
  384.          }
  385.  
  386.                                            /* Display the bottom line         */
  387.       if ( (num = digit[j].bot) != dsave[i][6] ) { /* only if it has changed  */
  388.          dsave[i][6] = num;                        /* save the new value      */
  389.          horiz_bar(num, row+12,col+1);
  390.          }
  391.      }
  392.  
  393.    /*                                                                         */
  394.    /* NOTE: dsave[][] is initially set to all zeros indicating the lines of   */
  395.    /* digits are all off.  This way the first time through only what is needed*/
  396.    /* to be displayed will be sent to the screen.                             */
  397.    /*                                                                         */
  398.  
  399. }
  400.  
  401.  
  402.  
  403. /******************************************************************************
  404. **  Draw or clear  a horizonatal bar on the screen
  405. **   This uses VS_PUTS to display a string
  406. */
  407.  
  408. static char *hbar = "      ";             /* Bar is a string of spaces        */
  409.  
  410. horiz_bar(turn_on,row,col)
  411. int turn_on,row,col;
  412. {
  413.  
  414.    if (turn_on) {                          /* If the bar should be turned     */
  415.       vid_puts(hbar,row,col,reverse);      /* ON then use VS_PUTS to display  */
  416.       }                                    /* the spaces in REVERSE video     */
  417.  
  418.    else {                                  /* If the bar should be turned     */
  419.       vid_puts(hbar,row,col,normal);       /* OFF then use VS_PUTS to display */
  420.       }                                    /* the spaces in NORMAL video      */
  421. }
  422.  
  423. /******************************************************************************
  424. **  Draw or clear  a vertical bar on the screen
  425. **   This uses VS_PUTC to display characters
  426. */
  427.  
  428. static char vchar  = ' ';
  429.  
  430.  
  431. vertl_bar(turn_on,row,col)
  432. int turn_on,row,col;
  433. {
  434.    register unsigned vpos = row;
  435.    register unsigned hpos = col;
  436.  
  437.    if (turn_on) {                          /* If the bar should be turned     */
  438.       for ( ; vpos < row + 5; vpos++)      /* ON then use VS_PUTC to fill     */
  439.          vid_putc(vchar,vpos,hpos,reverse);/* the area with spaces in         */
  440.       }                                    /* REVERSE video                   */
  441.  
  442.    else {                                  /* If the bar should be turned     */
  443.      for ( ; vpos < row + 5; vpos++)       /* OFF then use VS_PUTC to fill    */
  444.          vid_putc(vchar,vpos,hpos,normal); /* the area with spaces in         */
  445.       }                                    /* NORMAL video                    */
  446. }
  447.  
  448.  
  449. /******************************************************************************/
  450.  
  451. keyflags()
  452. {
  453.    union REGS regs;                        /* Use function 1 of interrupt 16  */
  454.    regs.h.ah = 0x2;                        /* to return the shift key state.  */
  455.    int86(0x16,®s,®s);                /* It is interesting that Windows  */
  456.    return(regs.h.al);                      /* and DESQview return the actual  */
  457. }                                          /* shift state setting instead of  */
  458.                                            /* maintaining a separate process  */
  459.                                            /* shift status.                   */
  460. /******************************************************************************/
  461.  
  462. getkey()
  463. {
  464.    union REGS regs;                        /* Use function 0 of interrupt 16  */
  465.    regs.h.ah = 0x0;                        /* to return keyboard input.       */
  466.    int86(0x16,®s,®s);                /* Here DESQview and Windows       */
  467.    return(regs.h.al);                      /* intercept this call and return  */
  468. }                                          /* a keystroke for the calling     */
  469.                                            /* process.                        */
  470. /******************************************************************************/
  471.  
  472. getdostime(hour,minute,second)
  473. char *hour;
  474. char *minute;
  475. char *second;
  476. {
  477.    union REGS regs;                        /* Issue DOS function 2C to return */
  478.    regs.h.ah = 0x2C;                       /* the system time.                */
  479.    int86(0x21,®s,®s);
  480.    *hour = regs.h.ch;
  481.    *minute = regs.h.cl;                    /* Store the returned value in the */
  482.    *second = regs.h.dh;                    /* global clock setting variables  */
  483. }
  484.  
  485. /******************************************************************************/
  486.